namespace Adge.Common
{    
    using System;
    using System.Collections;
    using System.Xml;

    public class CSCache
    {
        private CSCache()
        {
            this.rootXml = new XmlDocument();
            CSCache.cs = new DefaultCacheStrategy();
            this.objectXmlMap = this.rootXml.CreateElement("Cache");
            this.rootXml.AppendChild(this.objectXmlMap);
            LogVisitor visitor1 = new CacheLogVisitor();
            CSCache.cs.Accept(visitor1);
        }

        public virtual bool AddMultiObjects(string xpath, object[] objValue)
        {
            this.RemoveMultiObjects(xpath);
            if (((xpath != null) && (xpath != "")) && ((xpath.Length != 0) && (objValue != null)))
            {
                lock (objValue)
                {
                    for (int num1 = 0; num1 < objValue.Length; num1++)
                    {
                        this.AddObject(xpath + "/Multi/_" + num1.ToString(), objValue[num1]);
                    }
                }
                return true;
            }
            return false;
        }

        public virtual bool AddMultiObjects(string xpath, object[] objValue, int timeount)
        {
            this.RemoveMultiObjects(xpath);
            if (((xpath != null) && (xpath != "")) && ((xpath.Length != 0) && (objValue != null)))
            {
                lock (objValue)
                {
                    for (int num1 = 0; num1 < objValue.Length; num1++)
                    {
                        this.AddObject(xpath + "/Multi/_" + num1.ToString(), objValue[num1], timeount);
                    }
                }
                return true;
            }
            return false;
        }

        public virtual bool AddMultiObjects(string xpath, object[] objValue, string[] files)
        {
            this.RemoveMultiObjects(xpath);
            if (((xpath != null) && (xpath != "")) && ((xpath.Length != 0) && (objValue != null)))
            {
                lock (objValue)
                {
                    for (int num1 = 0; num1 < objValue.Length; num1++)
                    {
                        this.AddObject(xpath + "/Multi/_" + num1.ToString(), objValue[num1], files);
                    }
                }
                return true;
            }
            return false;
        }

        public virtual void AddObject(string xpath, object o)
        {
            this.RemoveObject(xpath);
            string text1 = this.PrepareXpath(xpath);
            int num1 = text1.LastIndexOf("/");
            string text2 = text1.Substring(0, num1);
            string text3 = text1.Substring(num1 + 1);
            XmlNode node1 = this.objectXmlMap.SelectSingleNode(text2);
            if (node1 == null)
            {
                lock (this)
                {
                    node1 = this.CreateNode(text2);
                }
            }
            string text4 = Guid.NewGuid().ToString();
            XmlElement element1 = this.objectXmlMap.OwnerDocument.CreateElement(text3);
            XmlAttribute attribute1 = this.objectXmlMap.OwnerDocument.CreateAttribute("objectId");
            attribute1.Value = text4;
            element1.Attributes.Append(attribute1);
            node1.AppendChild(element1);
            CSCache.cs.AddObject(text4, o);
        }

        public virtual void AddObject(string xpath, object o, int timeout)
        {
            CSCache.cs.TimeOut = timeout;
            this.AddObject(xpath, o);
        }

        public virtual void AddObject(string xpath, object o, string[] files)
        {
            this.RemoveObject(xpath);
            string text1 = this.PrepareXpath(xpath);
            int num1 = text1.LastIndexOf("/");
            string text2 = text1.Substring(0, num1);
            string text3 = text1.Substring(num1 + 1);
            XmlNode node1 = this.objectXmlMap.SelectSingleNode(text2);
            if (node1 == null)
            {
                lock (this)
                {
                    node1 = this.CreateNode(text2);
                }
            }
            string text4 = Guid.NewGuid().ToString();
            XmlElement element1 = this.objectXmlMap.OwnerDocument.CreateElement(text3);
            XmlAttribute attribute1 = this.objectXmlMap.OwnerDocument.CreateAttribute("objectId");
            attribute1.Value = text4;
            element1.Attributes.Append(attribute1);
            node1.AppendChild(element1);
            CSCache.cs.AddObjectWithFileChange(text4, o, files);
        }

        public virtual void AddSingleObject(string xpath, object o)
        {
            this.RemoveSingleObject(xpath);
            this.AddObject(xpath + "/Single", o);
        }

        public virtual void AddSingleObject(string xpath, object o, string[] files)
        {
            this.RemoveSingleObject(xpath);
            this.AddObject(xpath + "/Single", o, files);
        }

        public virtual void AddSingleObject(string xpath, object o, int timeout)
        {
            this.RemoveSingleObject(xpath);
            this.AddObject(xpath + "/Single", o, timeout);
        }

        private XmlNode CreateNode(string xpath)
        {
            string[] textArray1 = xpath.Split(new char[] { '/' });
            string text1 = "";
            XmlNode node1 = this.objectXmlMap;
            for (int num1 = 1; num1 < textArray1.Length; num1++)
            {
                if (this.objectXmlMap.SelectSingleNode(text1 + "/" + textArray1[num1]) == null)
                {
                    XmlElement element1 = this.objectXmlMap.OwnerDocument.CreateElement(textArray1[num1]);
                    node1.AppendChild(element1);
                }
                text1 = text1 + "/" + textArray1[num1];
                node1 = this.objectXmlMap.SelectSingleNode(text1);
            }
            return node1;
        }

        public static CSCache GetCacheService()
        {
            if (CSCache.cache == null)
            {
                CSCache.cache = new CSCache();
            }
            return CSCache.cache;
        }

        private string PrepareXpath(string xpath)
        {
            string[] textArray1 = xpath.Split(new char[] { '/' });
            xpath = "/Cache";
            foreach (string text1 in textArray1)
            {
                if (text1 != "")
                {
                    xpath = xpath + "/" + text1;
                }
            }
            return xpath;
        }

        public virtual void RemoveMultiObjects(string xpath)
        {
            try
            {
                XmlNode node1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath + "/Multi/"));
                if (node1.HasChildNodes)
                {
                    XmlNodeList list1 = node1.SelectNodes("*[@objectId]");
                    string text1 = "";
                    foreach (XmlNode node2 in list1)
                    {
                        text1 = node2.Attributes["objectId"].Value;
                        node2.ParentNode.RemoveChild(node2);
                        CSCache.cs.RemoveObject(text1);
                    }
                }
                else
                {
                    string text2 = node1.Attributes["objectId"].Value;
                    node1.ParentNode.RemoveChild(node1);
                    CSCache.cs.RemoveObject(text2);
                }
            }
            catch
            {
            }
        }

        public virtual void RemoveObject(string xpath)
        {
            try
            {
                XmlNode node1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath));
                if (node1.HasChildNodes)
                {
                    XmlNodeList list1 = node1.SelectNodes("*[@objectId]");
                    string text1 = "";
                    foreach (XmlNode node2 in list1)
                    {
                        text1 = node2.Attributes["objectId"].Value;
                        node2.ParentNode.RemoveChild(node2);
                        CSCache.cs.RemoveObject(text1);
                    }
                }
                else
                {
                    string text2 = node1.Attributes["objectId"].Value;
                    node1.ParentNode.RemoveChild(node1);
                    CSCache.cs.RemoveObject(text2);
                }
            }
            catch
            {
            }
        }

        public virtual void RemoveSingleObject(string xpath)
        {
            try
            {
                XmlNode node1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath + "/Single/"));
                if (node1.HasChildNodes)
                {
                    XmlNodeList list1 = node1.SelectNodes("*[@objectId]");
                    string text1 = "";
                    foreach (XmlNode node2 in list1)
                    {
                        text1 = node2.Attributes["objectId"].Value;
                        node2.ParentNode.RemoveChild(node2);
                        CSCache.cs.RemoveObject(text1);
                    }
                }
                else
                {
                    string text2 = node1.Attributes["objectId"].Value;
                    node1.ParentNode.RemoveChild(node1);
                    CSCache.cs.RemoveObject(text2);
                }
            }
            catch
            {
            }
        }

        public virtual object[] RetrieveMultiObjects(string xpath)
        {
            return this.RetrieveObjectList(xpath + "/Multi");
        }

        public virtual object RetrieveObject(string xpath)
        {
            XmlNode node1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath));
            if (node1 != null)
            {
                string text1 = node1.Attributes["objectId"].Value;
                return CSCache.cs.RetrieveObject(text1);
            }
            return null;
        }

        public virtual object[] RetrieveObjectList(string xpath)
        {
            XmlNodeList list1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath)).SelectNodes(this.PrepareXpath(xpath) + "/*[@objectId]");
            ArrayList list2 = new ArrayList();
            string text1 = null;
            foreach (XmlNode node2 in list1)
            {
                text1 = node2.Attributes["objectId"].Value;
                list2.Add(CSCache.cs.RetrieveObject(text1));
            }
            return (object[]) list2.ToArray(typeof(object));
        }

        public virtual object RetrieveSingleObject(string xpath)
        {
            object obj1 = null;
            XmlNode node1 = this.objectXmlMap.SelectSingleNode(this.PrepareXpath(xpath + "/Single"));
            if (node1 != null)
            {
                string text1 = node1.Attributes["objectId"].Value;
                obj1 = CSCache.cs.RetrieveObject(text1);
            }
            return obj1;
        }


        private static CSCache cache;
        private static ICacheStrategy cs;
        private XmlElement objectXmlMap;
        private XmlDocument rootXml;
    }
}

